package com.bpf.base.security;

import java.io.UnsupportedEncodingException;
import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.bpf.base.bean.system.TSysUserForm;
import com.bpf.base.model.system.TSysUser;
import com.bpf.base.service.system.TSysUserService;
import com.bpf.base.util.Collections3;
import com.bpf.base.util.MapUtil;

/**
 * 重写用户名密码验证
 * 
 * @author
 *
 */
public class CustomUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

	private final static Logger logger = LoggerFactory.getLogger(CustomUsernamePasswordAuthenticationFilter.class);

	// 验证码
	public static final String VALIDATE_CODE = "validateCode";
	// 用户名
	public static final String USERNAME = "username";
	// 密码
	public static final String PASSWORD = "password";
	//是否保存cookies
	public static final String REMINDPWD = "remindPWD";

	@Autowired
	private TSysUserService userService;

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
		
		if (!request.getMethod().equals("POST")) {
			throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
		}

		// 检测验证码
		// checkValidateCode(request);

		String username = obtainUsername(request);
		String password = obtainPassword(request);

		// 验证用户账号与密码是否对应
		username = username.trim();
		password = password.trim();
		TSysUserForm form=new TSysUserForm();
		form.setUsername(username);
		form.setPassword(password);
		List<TSysUser> users = userService.getAllTSysUser(MapUtil.toMap(form));
		if (Collections3.isEmpty(users)) {
			throw new AuthenticationServiceException("用户名或密码不正确.");
		}
		String remindPwd=request.getParameter(REMINDPWD);
		if(remindPwd!=null){
			Cookie cookie=new Cookie("uname", username);
			Cookie cookie1=new Cookie("pword", password);
			cookie.setPath("/");			//存储地址，必须要加，
			cookie.setMaxAge(60*60*24*30);	//一个月的生存周期，必须要加，
			cookie1.setPath("/");
			cookie1.setMaxAge(60*60*24*30);
			response.addCookie(cookie);
			response.addCookie(cookie1);
		}
		
		// UsernamePasswordAuthenticationToken实现 Authentication
		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
		// Place the last username attempted into HttpSession for views

		// 允许子类设置详细属性
		setDetails(request, authRequest);

		// 运行UserDetailsService的loadUserByUsername 再次封装Authentication
		return this.getAuthenticationManager().authenticate(authRequest);
	}

	protected void checkValidateCode(HttpServletRequest request) {
		HttpSession session = request.getSession();

		String sessionValidateCode = obtainSessionValidateCode(session);
		// 让上一次的验证码失效
		session.setAttribute(VALIDATE_CODE, null);
		String validateCodeParameter = obtainValidateCodeParameter(request);
		if (StringUtils.isEmpty(validateCodeParameter) || !sessionValidateCode.equalsIgnoreCase(validateCodeParameter)) {
			throw new AuthenticationServiceException("验证码错误！");
		}
	}

	private String obtainValidateCodeParameter(HttpServletRequest request) {
		Object obj = request.getParameter(VALIDATE_CODE);
		return null == obj ? "" : obj.toString();
	}

	protected String obtainSessionValidateCode(HttpSession session) {
		Object obj = session.getAttribute(VALIDATE_CODE);
		return null == obj ? "" : obj.toString();
	}

	@Override
	protected String obtainUsername(HttpServletRequest request) {
		try {
			request.setCharacterEncoding("UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		Object obj = request.getParameter(USERNAME);
		return null == obj ? "" : obj.toString();
	}

	@Override
	protected String obtainPassword(HttpServletRequest request) {
		Object obj = request.getParameter(PASSWORD);
		return null == obj ? "" : obj.toString();
	}

}
